#include <pcap.h>

#include "pcap_task.h"
#include "pcap_process.h"
#include "uthash.h"
#include "use_hash.h"
#include "task_manager.h"
#include "task.h"
#include "log.h"

#include "buff_queue.h"
#include "Common.h"
#include<stdio.h>

#include<mysql/mysql.h>

#include"dispatch.h"

#include"balance.h"

#include"client_connect.h"

unsigned long raw_packet_count = 0;
unsigned long ipv4_packet_count = 0;


record_t *head = NULL;
struct client_connect *CC=NULL;

MYSQL mysql;

struct task_manager *Task_manager=NULL;
struct core_conf *Core_conf=NULL;

struct buff_queue * Buffer_queue=NULL;

pcap_t *pcap_handle = NULL;

struct sockaddr_in *need_dispatched_client = NULL;

struct fib * Fib = NULL;

void init_sock_fd()
{

	
	core_conf_init_node(Core_conf,Core_conf->node_file);
	core_conf_init_server(&Core_conf->server,Core_conf->server_file);
	core_conf_init_server(&Core_conf->balance_server,Core_conf->balance_file);		
		
	Core_conf->local_addr=(struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
	

	//this is to init the socket send as a client
	
	Core_conf->sock_fd=init_addr_client(Core_conf->server,Core_conf->local_addr);
		
	Core_conf->balance_addr=(struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
	Core_conf->sock_balance=init_addr_client(Core_conf->balance_server,Core_conf->balance_addr);

	CC=(struct client_connect *)malloc(sizeof(struct client_connect));

	init_client_connect(CC);

	print_socket_info();
	
	//get_dispathed();
	

	int i=0;

	for(i=0;i<Core_conf->Node_conf.node_num;i++)
	{
		printf("node hostname:%s\n",Core_conf->Node_conf.Node[i].hostname);
		printf("node port:%d\n",Core_conf->Node_conf.Node[i].port);
		printf("node ip:%s\n",inet_ntoa(Core_conf->Node_conf.Node[i].ip));
	}

}

void init_env()
{
	log_open(TASK_NAME);
	
	log_info("env init successful");
	
}


void init_rel()
{
	buff_queue_init(&Buffer_queue);	
	
	//init the center value task_manager
	Task_manager=task_manager_create();
	//init the core_conf
	Core_conf=(struct core_conf *)malloc(sizeof(struct core_conf));

	char *core_file="./conf/core_config";
	Core_conf->core_conf_file=(char *)malloc(strlen(core_file)+1);
	strcpy(Core_conf->core_conf_file,core_file);

  	core_conf_from_file(Core_conf,Core_conf->core_conf_file);     

	init_sock_fd();
	//log init	
	
	
	//init the task_manager and give it initial value

	task_manager_init(Task_manager,Core_conf);
	
	task_manager_finish(Task_manager);

	//need_dispatched_client init

	need_dispatched_client=CC->head[0].Node;

	//next is pcap init

	printf("begin pcap_init\n");
	log_info("begin pcap_init\n");

	if(Core_conf->pcap_mode==1)
	{
		pcap_handle = pcap_init(Core_conf->pcap_mode,Core_conf->pcap_file,Core_conf->pcap_interface);
	}
	else if(Core_conf->pcap_mode==0)
	{
		pcap_handle = pcap_init(Core_conf->pcap_mode,"./pcap_offline/packet","eth0");
	}
	else
	{
		log_error("pcap mode is wrong");
		exit(0);
	}
	
	if (pcap_handle == NULL) {
		printf("pcap_handle is NULL.");
		printf("can not init pcap handle");
		/* TODO:kill task */
		return;
	}
	printf("pcap init successfully\n");
	log_info("pcap init successfully");


	//next is mysql init

	printf("begin mysql init\n");
	log_info("begin mysql init");

        mysql_init(&mysql);

        if(mysql_real_connect(&mysql,"localhost","root","123456","sklccdpi",0,NULL,0))
        {
                printf("mysql connect successfully\n");
		log_info("mysql connect successfully");
        }
        else
        {
                printf("mysql connect fail");
		log_error("mysql connect fail");
		return;
        }
}

int main()
{
	init_env();
	init_rel();

	
	//add task socket to the task_manager
	
	register_plugin_task(Task_manager,"socket_send",dispatch);
	register_plugin_task(Task_manager,"balance_get",get_dispathed);
	
	start_task(Task_manager);

	int res;
	res = mysql_query(&mysql,"create table pcapTableInfo(id int, tableName char(128))");
	if (res) {
		printf("sql_query error:%s\n",mysql_error(&mysql));
	}

	pcap_loop(pcap_handle, -1, &pcap_task_packet_process, NULL);

	/* NOT REACHED HERE */
	return 0;
}
